package file

import (
	"os"
	"sync"
	"gitee.com/kmyss/base-tool/errcode"
)

const baseCode = 2000

var (
	// NoCreateError 文件没有创建异常
	NoCreateError = errcode.NewError(baseCode, "文件没有创建")
	// CanNotCreateError 无法创建文件异常
	CanNotCreateError = errcode.NewError(baseCode+1, "文件无法创建")
)

// FileWriteHandler 一个支持线程操作操作的写文件对象
type FileWriteHandler struct {
	filePath string      // 文件路径
	writeCh  chan []byte //
	outFile  *os.File    // 回放文件句柄

	isCreate bool // 是否已开启
	wg       sync.WaitGroup
}

// NewFileWriteHandler 建立一个文件
func NewFileWriteHandler(filePath string, channelSize int) (*FileWriteHandler, error) {
	return &FileWriteHandler{
		filePath: filePath,
		writeCh:  make(chan []byte, channelSize),
		outFile:  nil,
		isCreate: false,
	}, nil
}

// Create ...
func (f *FileWriteHandler) Create() error {
	var err error
	f.outFile, err = os.Create(f.filePath)
	if err != nil {
		return CanNotCreateError
	}
	go f._writer()
	f.wg.Add(1)
	f.isCreate = true
	return nil
}

// Write 实现Writter接口
func (f *FileWriteHandler) Write(p []byte) (n int, err error) {
	if f.isCreate {
		f.writeCh <- p
		return len(p), nil
	} else {
		return 0, NoCreateError
	}
}

// _writer 写文件线程
func (f *FileWriteHandler) _writer() {
	for date := range f.writeCh {
		f.outFile.Write(date)
	}
	f.wg.Done()
}

// Close ...
func (f *FileWriteHandler) Close() {
	close(f.writeCh)

	f.wg.Wait()
	f.outFile.Sync()
	f.outFile.Close()

}
